# coding:utf-8
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, session
import time
import os

from operate_database import get_userinfo_from_db, insert_point_to_db, get_names, get_questions
from operate_database import insert_registerMessage_to_db, select_unitTesting_complete, insert_unitTesting_complete
from operate_database import get_pre_questions, select_preTesting_complete, insert_preTesting_complete   # 前测相关组件1
from operate_database import VARK, insert_preResult_to_db  # 前测相关组件2
from operate_database import select_groupTask_info, select_groupID  # 小组任务（内容获取）相关组件1
from operate_database import select_is_grouped  # 小组任务（内容获取）相关组件3

from operate_file import save_comment, read_comments  # 小组任务（讨论区）相关组件2
from operate_file import write_yesResult_to_txt, write_noResult_to_txt
from operate_file import write_loginMessage_to_txt, remove_name_lines
from operate_file import write_chat_history  # chat历史记录组件

from WenXin import get_response  # 大模型相关组件
# from PDDPDDPDD import get_response  # 大模型相关组件

from group_task_assessment import assess

app = Flask(__name__, template_folder='templates')  # app实例
app.secret_key = 'Serein'
app.config['DEBUG'] = False  # False是关


# 根目录
@app.route('/')  # 根目录
def index():
    return render_template('login.html')


# 登录组件，路由：/login
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    elif request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        info_u_p = get_userinfo_from_db()
        if username in info_u_p.keys() and password == info_u_p[username][0]:
            flash('登录成功', 'success')
            session['username'] = username
            print(f"*****[后台进度信息] SESSION创建完成！验证信息: 'username': {session['username']}")
            user_data = {'username': username, 'password': password}
            info = f"*****[登陆验证信息] 用户 '{username}' 登录成功"
            print(info)
            write_loginMessage_to_txt(info + f"\t请求时间:{time.asctime()}" + '\n')
            return render_template('mainview_1.html', data=user_data, error_2=0, is_group=1)  # 0表示欢迎
        else:
            error_0 = 1  # 发送给前端的错误信息，用于触发前端的弹窗提示
            print(f"*****[登陆验证信息] 登陆失败, 登录信息: '用户名: {username}, 密码: {password}'")
            flash('登陆失败，用户名或密码错误', 'danger')
            return render_template('login.html', data=error_0)


# 注册组件，路由 /register
@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'GET':
        return render_template('register.html')
    elif request.method == 'POST':
        user_name = request.form.get('username')
        password = request.form.get('password')
        password2 = request.form.get('password2')
        if user_name in get_names():
            error_1 = 1  # 发送给前端的错误信息，用于触发前端的弹窗提示
            print(f"*****[登陆验证信息] 注册失败, 原因: 用户名: '{user_name}'已经存在")
            return render_template('register.html', data=error_1)
        else:
            if len(user_name) >= 10:
                error_1 = 3
                print(f"*****[登陆验证信息] 注册失败，原因: 用户名: '{user_name} 长度过长'")
                return render_template('register.html', data=error_1)
            elif len(user_name) <= 1:
                error_1 = 4
                print(f"*****[登陆验证信息] 注册失败，原因: 用户名: '{user_name} 长度过短'")
                return render_template('register.html', data=error_1)
            else:
                if len(password) <= 5:
                    error_1 = 5
                    print(f"*****[登陆验证信息] 注册失败，原因: 用户名: '{user_name} 使用的密码长度过短'")
                    return render_template('register.html', data=error_1)
                elif len(password) >= 18:
                    error_1 = 6
                    print(f"*****[登陆验证信息] 注册失败，原因: 用户名: '{user_name} 使用的密码长度过长'")
                    return render_template('register.html', data=error_1)
                else:
                    if password != password2:
                        error_1 = 2
                        print(f"*****[登陆验证信息] 注册失败, 原因: 用户名: '{user_name}'输入的两次密码不同")
                        return render_template('register.html', data=error_1)
                    else:
                        error_1 = 0
                        insert_registerMessage_to_db(user_name, password)
                        return render_template('login.html', data=error_1)


# 返回主页(跳转)组件
@app.route('/to_mainview_1', methods=['GET', 'POST'])
def to_mainview_1():
    print(f"*****[用户行为信息] 用户 {session['username']} 返回主页")
    return render_template("mainview_1.html", data={'username': session['username']}, error_2=0, is_group=1)


# 学习者类型前测控制组件
@app.route('/pre_test', methods=['GET', 'POST'])
def pre_test():
    if request.method == 'GET':
        print(f"*****[用户行为信息] 用户 {session['username']} 请求进行学习风格测试")
        status = select_preTesting_complete(session['username'])
        if status == "1":  # 表示已经提交过这次测试
            print(f"*****[用户行为信息] 用户 {session['username']} 请求进行前测失败。 错误: 已经完成")
            return render_template('mainview_1.html', error_2=1, is_group=1, data={'username': session['username']})
        else:
            return render_template("pre_test.html", questions=get_pre_questions(), end=0)  # 0表示未完成

    elif request.method == 'POST':
        print(f"*****[用户行为信息] 用户 {session['username']} 完成前测。")
        user_result, result_num = [], {'V': 0, 'A': 0, 'R': 0, 'K': 0}
        for key in request.form:
            if key.startswith('q'):  # 表单字段以 "q" 开头，表示单个问题的答案
                user_result.append(int(request.form[key]))

        mapping = {1: 'V', 2: 'A', 3: 'R', 4: 'K'}  # 映射
        for i in [mapping[num] for num in user_result]:  # 列表中储存各题的选项，方便统计数量
            result_num[i] += 1
        highest_key = max(result_num, key=result_num.get)  # 数量最多的选项
        result = VARK[highest_key]

        insert_preTesting_complete(session['username'])  # 在数据库users表中，将preTesting字段置为 ‘1’，表示已完成。同时输出后台进度信息
        insert_preResult_to_db(session['username'], highest_key)  # 将对应结果写入数据库中
        return render_template("pre_test.html", result=result, end='1')  # 1表示已完成，进行弹窗展示结果


# 单元测试跳转组件（跳转）（error_2为0时表示欢迎，为1时表示已经完成题目）
@app.route('/to_unit_testing/<string:unit>', methods=['POST', 'GET'])
def to_unit_testing(unit):
    print(f"*****[用户行为信息] 用户 {session['username']} 请求进行第 {int(unit)} 单元测试")
    status = select_unitTesting_complete(session['username'], unit)
    if status == "1":  # 表示已经提交过这次测试
        print(f"*****[用户行为信息] 用户 {session['username']} 请求单元测试{int(unit)}失败。 错误: 已经完成")
        return render_template('mainview_1.html', error_2=1, is_group=1, data={'username': session['username']})
    else:  # 若用户没有做过（提交过）这个测试
        print(f"*****[用户行为信息] 用户 {session['username']} 请求单元测试{int(unit)}成功。")
        return render_template('unit_testing.html', questions=get_questions(unit), unit=unit)


# 单元测试检查组件
@app.route('/check_unit_testing/<string:unit>', methods=['POST'])
def check_unit_testing(unit):
    answers_num = []
    for key in request.form:
        if key.startswith('q'):  # 表单字段以 "q" 开头，表示单个问题的答案
            answers_num.append(int(request.form[key]))
    mapping = {1: 'A', 2: 'B', 3: 'C', 4: 'D'}  # 映射
    answers = [mapping[num] for num in answers_num]

    questions = get_questions(unit)
    score = 0
    for i, answer in enumerate(answers):
        if answer == questions[i]['answer']:
            write_yesResult_to_txt(session['username'], questions[i]['point'])
            score += 10
        else:
            write_noResult_to_txt(session['username'], questions[i]['point'])
    insert_point_to_db(session['username'])  # 将数据写入数据库（users表）
    remove_name_lines(session['username'])  # 删除txt中对应的用户信息
    print(f"*****[用户行为信息] 用户: {session['username']} 第{unit}单元测试得分: {score}")
    insert_unitTesting_complete(session['username'], unit)

    return render_template('testing_analyze.html', questions=get_questions(unit),
                           answer_user=answers, data={"score": score, "total": len(questions) * 10}, mapping=mapping)


# LLM问答助手message组件
@app.route('/ai', methods=['POST'])
def ai():
    data = request.get_json()  # 前端发送的数据
    user_message = data.get('message')
    print(f"*****[用户行为信息] 用户 {session['username']} 向LLM助手发送信息: {user_message}")

    response = get_response(session['username'], user_message)  # 该方法可以从数据库获取用户关键词
    print(f"*****[后台进度信息] AI给出用户 {session['username']} 的回答: {response}")
    # write_chat_history(session['username'], user_message, response)  # 写入历史记录
    return jsonify({'response': response})


# 个人中心跳转组件，路由：/individual_center
@app.route('/individual_center')
def individual_center():
    print(f"*****[用户行为信息] 用户 {session['username']} 访问个人中心")
    userinfo = get_userinfo_from_db()
    return render_template('individual_center.html',
                           userInfo={'username': session['username'], 'point': userinfo[session['username']][1]})


# 小组任务组件 路由：/group_task
@app.route('/group_task', methods=['GET', 'POST'])
def group_task():
    if request.method == 'GET':
        print(f"*****[用户行为信息] 用户 {session['username']} 请求访问小组任务评论界面")
        is_group = select_is_grouped(session['username'])  # 0 代表未分组，1 代表已经有分组

        if is_group == 0:
            return render_template('mainview_1.html', error_2=0, is_group=0, data={'username': session['username']})

        else:
            groupID = select_groupID(session['username'])
            groupMember = select_groupTask_info(1, session['username'])  # 小组成员 列表[字符串]
            groupTask = select_groupTask_info(2, session['username'])  # 小组任务 字符串
            comments = read_comments(groupID)
            return render_template('group_task.html', groupID=groupID, groupMember=groupMember,
                                   groupTask=groupTask, comments=comments)

    elif request.method == 'POST':
        groupID = select_groupID(session['username'])
        # username = session.get('username', 'Guest')
        comment = request.form.get('comment')
        print(f"*****[用户请求信息] 用户 {session['username']} 发布小组评论: {comment}")
        if comment:
            save_comment(groupID, session['username'], comment)
        return redirect('/group_task')  # 提交后刷新页面，显示新的评论


# 小组作业测评组件 路由：/group_task_assessment
@app.route('/group_task_assessment', methods=['GET', 'POST'])
def group_task_assessment():
    if request.method == 'GET':
        is_group = select_is_grouped(session['username'])  # 0 代表未分组，1 代表已经有分组

        if is_group == 0:
            return render_template('mainview_1.html', error_2=0, is_group=0, data={'username': session['username']})

        else:
            task = select_groupTask_info(2, session['username'])
            return render_template('group_task_assessment.html', task=task, groupID=select_groupID(session['username']))

    if request.method == 'POST':
        task_description = request.form['task_description']  # 读取作业说明
        file = request.files['file_upload']  # 获取文件

        if file:  # 检查文件是否存在
            print(f"*****[用户行为信息] {select_groupID(session['username'])}组任务结果提交完毕")

            file_path = os.path.join('./uploads', f"{select_groupID(session['username'])}组小组作业__"+file.filename)
            file.save(file_path)  # 保存文件到服务器


if __name__ == '__main__':
    app.run(host='0.0.0.0')